package spolipar.bitcoin.bot.data;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import spolipar.bitcoin.bot.S;

/** Thread to fetch data */
public class DataFetcherTask extends Thread {
	
	private final MarketDataType[] m_dataToFetch;
	private final Map<MarketDataType, IMarketData> m_fetchedData = new ConcurrentHashMap<MarketDataType, IMarketData>();
	private final DataFetcher m_fetcher;
	private final String m_name;
	private final long m_pace;
	private boolean m_interrupted;
	private boolean m_pause;
	
	public DataFetcherTask(DataFetcher fetcher, MarketDataType[] dataToFetch, String name, long pace) {
		m_dataToFetch = dataToFetch;
		m_fetcher = fetcher;
		m_name = name;
		m_pace = Math.max(1020, pace);
	}
	
	public void pause(boolean v) {
		if(v ^ m_pause) { //clear data
			m_fetchedData.clear(); 
		}
		m_pause = v;
	}
		
	public IMarketData get(MarketDataType type ) { return m_fetchedData.get(type); }
	
	public void run() {
		while (!m_interrupted) {
			try {
				if(!m_pause) {
					MarketDataType type = dataToFetchNow();
					IMarketData data = m_fetcher.fetchData(type);
					m_fetchedData.put(type, data);
					LiveDataStorage.instance().put(m_fetcher.sotrageKey(), data);
				}
				Thread.currentThread().sleep(m_pace);
			} catch (InterruptedException e) {
				m_interrupted = true;
			} catch (IOException e) {
				m_interrupted = true;
				S.err(e);
			}
		}
	}
	
	private MarketDataType dataToFetchNow() {
		IMarketData oldest = null;
		for (MarketDataType type : m_dataToFetch) {
			IMarketData data =  m_fetchedData.get(type);
			if(data == null) {
				return type;
			}
			
			oldest = oldest == null 
					 ? data 
				     : oldest.getTimestamp() >  data.getTimestamp()
				       ? oldest
				       : data;		   
				     
		}
		
		return oldest.type();
	}
	
	@Override public String toString() {
		return m_name + " pause=" + m_pause + " dataSize=" + m_fetchedData.size();
	}
	
}
